package top.ieei.demo.tftp;

/**
 * 
 * TFTP文件传输数据包<br>
 * @author xiecongshu
 */
public class TftpData extends TftpAck
{
    /**
     * 数据位置索引:4
     */
    private static final int INDEX_DATA = 4;
    
    /**
     * 数据包响应操作码：3
     */
    public static final int OPCODE = 3;
    
    /**
     * 数据
     */
    private byte[] data = {};
    
    /**
     * <默认构造函数>
     * @exception TftpException
     */
    public TftpData() throws TftpException
    {
        super();
    }
    
    /**
     * <默认构造函数>
     * @exception TftpException
     */
    public TftpData(int blockNum, byte[] data) throws TftpException
    {
        this(blockNum, data, 0, data.length);
    }
    
    /**
     * <默认构造函数>
     * 通过UDP数据构建TFTP数据包响应
     * @exception TftpException
     */
    public TftpData(int blockNum, byte[] data, int offset, int len)
            throws TftpException
    {
        super(blockNum);
        try
        {
            this.data = new byte[len];
            System.arraycopy(data, offset, this.data, 0, len);
        }
        catch (Exception e)
        {
            throw new TftpException(
                    "Data passed to constructor of TftpData is invalid! "
                            + e.getMessage());
        }
    }
    
    /**
     * 通过UDP数据构建TFTP数据包响应
     * <默认构造函数>
     * @exception TftpException
     */
    public TftpData(byte[] tftpBytes, int tftpBytesLength) throws TftpException
    {
        super(tftpBytes);
        
        try
        {
            if (tftpBytesLength > tftpBytes.length)
            {
                tftpBytesLength = tftpBytes.length;
            }
            
            int len = tftpBytesLength - INDEX_DATA;
            data = new byte[len];
            System.arraycopy(tftpBytes, 4, data, 0, len);
        }
        catch (Exception e)
        {
            throw new TftpException(e);
        }
    }
    
    /**
     * 获取响应数据的字节数组<br>
     * 
     * @return byte[]
     */
    public byte[] getBytes()
    {
        int tftpLen = MIN_PACKET_SIZE;
        if (data != null)
        {
            tftpLen += data.length;
        }
        
        byte[] tftpBytes = new byte[tftpLen];
        
        // 加入两字节操作码
        tftpBytes[INDEX_OPCODE] = (byte) ((OPCODE >> 8) & 0xff);
        tftpBytes[INDEX_OPCODE + 1] = (byte) (OPCODE & 0xff);
        
        // 加入两字节数据块编号
        tftpBytes[INDEX_BLOCKNUM] = (byte) ((blockNum >> 8) & 0xff);
        tftpBytes[INDEX_BLOCKNUM + 1] = (byte) (blockNum & 0xff);
        
        // 加入文件数据
        System.arraycopy(data, 0, tftpBytes, INDEX_DATA, data.length);
        return tftpBytes;
    }
    
    /**
     * 获取传输的文件数据
     * @return byte[]
     */
    public byte[] getData()
    {
        return data;
    }
    
    /**
     * 获取操作码
     * @return int
     */
    public int getOpCode()
    {
        return OPCODE;
    }
}
